package com.rabtman.common.utils;

import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.View;
import android.view.ViewGroup;

/**
 * <pre>
 *     author: Blankj
 *     blog  : http://blankj.com
 *     time  : 2016/08/02
 *     desc  : 尺寸相关工具类
 * </pre>
 */
public final class SizeUtils {

  private SizeUtils() {
    throw new UnsupportedOperationException("u can't instantiate me...");
  }

  /**
   * dp转px
   *
   * @param dpValue dp值
   * @return px值
   */
  public static int dp2px(float dpValue) {
    final float scale = Utils.getContext().getResources().getDisplayMetrics().density;
    return (int) (dpValue * scale + 0.5f);
  }

  /**
   * px转dp
   *
   * @param pxValue px值
   * @return dp值
   */
  public static int px2dp(float pxValue) {
    final float scale = Utils.getContext().getResources().getDisplayMetrics().density;
    return (int) (pxValue / scale + 0.5f);
  }

  /**
   * sp转px
   *
   * @param spValue sp值
   * @return px值
   */
  public static int sp2px(float spValue) {
    final float fontScale = Utils.getContext().getResources().getDisplayMetrics().scaledDensity;
    return (int) (spValue * fontScale + 0.5f);
  }

  /**
   * px转sp
   *
   * @param pxValue px值
   * @return sp值
   */
  public static int px2sp(float pxValue) {
    final float fontScale = Utils.getContext().getResources().getDisplayMetrics().scaledDensity;
    return (int) (pxValue / fontScale + 0.5f);
  }

  /**
   * 各种单位转换
   * <p>该方法存在于TypedValue</p>
   *
   * @param unit 单位
   * @param value 值
   * @param metrics DisplayMetrics
   * @return 转换结果
   */
  public static float applyDimension(int unit, float value, DisplayMetrics metrics) {
    switch (unit) {
      case TypedValue.COMPLEX_UNIT_PX:
        return value;
      case TypedValue.COMPLEX_UNIT_DIP:
        return value * metrics.density;
      case TypedValue.COMPLEX_UNIT_SP:
        return value * metrics.scaledDensity;
      case TypedValue.COMPLEX_UNIT_PT:
        return value * metrics.xdpi * (1.0f / 72);
      case TypedValue.COMPLEX_UNIT_IN:
        return value * metrics.xdpi;
      case TypedValue.COMPLEX_UNIT_MM:
        return value * metrics.xdpi * (1.0f / 25.4f);
    }
    return 0;
  }

  /**
   * 在onCreate中获取视图的尺寸
   * <p>需回调onGetSizeListener接口，在onGetSize中获取view宽高</p>
   * <p>用法示例如下所示</p>
   * <pre>
   * SizeUtils.forceGetViewSize(view, new SizeUtils.onGetSizeListener() {
   *     Override
   *     public void onGetSize(View view) {
   *         view.getWidth();
   *     }
   * });
   * </pre>
   *
   * @param view 视图
   * @param listener 监听器
   */
  public static void forceGetViewSize(final View view, final onGetSizeListener listener) {
    view.post(new Runnable() {
      @Override
      public void run() {
        if (listener != null) {
          listener.onGetSize(view);
        }
      }
    });
  }

  /**
   * 测量视图尺寸
   *
   * @param view 视图
   * @return arr[0]: 视图宽度, arr[1]: 视图高度
   */
  public static int[] measureView(View view) {
    ViewGroup.LayoutParams lp = view.getLayoutParams();
    if (lp == null) {
      lp = new ViewGroup.LayoutParams(
          ViewGroup.LayoutParams.MATCH_PARENT,
          ViewGroup.LayoutParams.WRAP_CONTENT
      );
    }
    int widthSpec = ViewGroup.getChildMeasureSpec(0, 0, lp.width);
    int lpHeight = lp.height;
    int heightSpec;
    if (lpHeight > 0) {
      heightSpec = View.MeasureSpec.makeMeasureSpec(lpHeight, View.MeasureSpec.EXACTLY);
    } else {
      heightSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
    }
    view.measure(widthSpec, heightSpec);
    return new int[]{view.getMeasuredWidth(), view.getMeasuredHeight()};
  }

  /**
   * 获取测量视图宽度
   *
   * @param view 视图
   * @return 视图宽度
   */
  public static int getMeasuredWidth(View view) {
    return measureView(view)[0];
  }

  /**
   * 获取测量视图高度
   *
   * @param view 视图
   * @return 视图高度
   */
  public static int getMeasuredHeight(View view) {
    return measureView(view)[1];
  }

  /**
   * 获取到View尺寸的监听
   */
  public interface onGetSizeListener {

    void onGetSize(View view);
  }
}